//  默认表单的绑定的modle 为 form  ref 也为 from  校验信息为 tips 如果绑定的不是这种格式则不适用

/**
 * 表单校验mixins
 * props:
 *      rules: 校验规则 type: Object  ({key: Function} 形式  Function 接受  表单值 value 返回 校验错误信息)
 */
export const formRules = {
    props: {
        // 校验规则 规则中的this 指向当前组件
        rules: {
            type: Object,
            default: function () {
                return {}
            }
        }
    },
    data () {
        return {
            tips: {}
        }
    },
    computed: {
        formRules () {
            let keys = Object.keys(this.rules)
            let rules = {}
            keys.forEach(key => {
                rules[key] = [
                    {
                        validator: this.validator,
                        trigger: 'blur'
                    }
                ]
            })
            return Object.freeze(rules)
        }
    },
    methods: {
        validator (rule, value, callback) {
            const { field } = rule
            const err = this.rules[field].call(this, value)
            this.tips[field] = err
            err ? callback(new Error(err)) : callback()
        }
    }
}

/**
 * 表单操作数据方法mixins
 * methods:
 *      resetForm 重置表单所有数据及错误提示信息
 *      setFormTips 设置表单错误信息
 *      getFormTips 获取表单错误信息
 *      clearFormTips 清空表单错误信息
 *      getFormByKey 获取表单某个字段的数据
 *      setFormData 设置表单数据(支持 单个或批量修改)
 *      validateField 校验单个字段
 *      validate 校验表单
 *
 */
export const formMethods = {
    data () {
        return {
            tips: {}
        }
    },
    methods: {
        // 重置表单数据方法
        resetForm () {
            Object.keys(this.form).forEach(k => {
                this.form[k] = ''
            })
            this.form.customsDeclareEdocRealas = []
            this.$nextTick(() => {
                this.clearFormTips()
            })
        },
        /**
         * 设置某个字段错误提示信息
         * @param {String, Object} key 传入对象可设置多个字段
         * @param {String} value key 为 String 时候 的 值
         */
        setFormTips (key, value) {
            if (Object.prototype.toString.call(key) === '[object Object]') {
                Object.keys(key).forEach(k => {
                    if (this.tips.hasOwnProperty(k)) {
                        this.tips[k] = key[k]
                    }
                })
            } else {
                if (this.tips.hasOwnProperty(key)) {
                    this.tips[key] = value || ''
                }
            }
        },
        /**
         * 获取某个字段校验的信息
         * @param {String, Array} key 传入数组可获取多个字段
         * @param {String} value key 为 String 时候 的 值
         * @returns {String, Array}
         */
        getFormTips (key) {
            if (key === undefined) return JSON.parse(JSON.stringify(this.tips))
            if (Object.prototype.toString.call(key) === '[object Array]') {
                return key.map(k =>
                    this.tips.hasOwnProperty(k) ? this.tips[k] : ''
                )
            }
            return this.tips.hasOwnProperty(key) ? this.tips[key] : ''
        },
        /**
         * 清空所有校验信息方法
         * @param {Array} keys 需要清空的字段名 不传或传空数组会清空所有
         */
        clearFormTips (keys = []) {
            (keys.length ? keys : Object.keys(this.tips)).forEach(key => {
                this.tips[key] = ''
            })
        },
        /**
         * 获取表单某个字段的数据
         * @param {Array} keys 需要查询的字段名 不传返回所有字段
         * @returns {String Array}
         */
        getFormByKey (key) {
            if (key === undefined) return JSON.parse(JSON.stringify(this.form))
            if (Object.prototype.toString.call(key) === '[object Array]') {
                return key.map(k =>
                    this.form.hasOwnProperty(k) ? this.form[k] : undefined
                )
            }
            return this.form.hasOwnProperty(key) ? this.form[key] : undefined
        },
        /**
         * 设置表单数据(支持 单个或批量修改)
         * @param {String, Object} key 传入对象可设置多个字段
         * @param {String} value key 为 String 时候 的 值
         */
        setFormData (key, value) {
            if (Object.prototype.toString.call(key) === '[object Object]') {
                Object.keys(key).forEach(k => {
                    if (this.form.hasOwnProperty(k)) {
                        this.form[k] = key[k]
                    }
                })
            } else if (this.form.hasOwnProperty(key)) {
                this.form[key] = value
            }
        },
        /**
         * 校验单个字段
         * @param {Stirng} key 需要将校验的字段
         * @param {Function} cb 回调函数 参数为校验错误信息
         * @param {String} refName 表单的 ref 值 默认 'form'
         */
        validateField (key, cb, refName = 'form') {
            const ref = this.$refs[refName]
            ref && ref.validateField(key, cb)
        },
        /**
         * 校验表单
         * @param {Function} cb 回调函数 参数为校验错误信息
         * @param {String} refName 表单的 ref 值 默认 'form'
         * @returns {Promise} 返回promise
         */
        validate (cb, refName = 'form') {
            const ref = this.$refs[refName]
            if (ref) {
                return ref.validate(cb)
            } else {
                cb(false)
                return Promise.resolve(false)
            }
        }
    }
}
